﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Diagnostics;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using Monitor.Utils;

namespace Monitor
{
    public partial class Form1 : Form
    {
        #region Class Variables

        GlobalHooks             _globalHooks;
        List<String>            _drives;
        string                  _previousEntry = "";
        bool                    _previousRedraw;
        bool                    _showEverything;
        List<String>            _knownLocations;
        Dictionary<String,int>  _mostPopularLocations;

        #endregion

        #region Constructors
        public Form1()
        {
            InitializeComponent();
            label1.Text = "Listening to: " + System.Security.Principal.WindowsIdentity.GetCurrent().Name;
            _globalHooks = new GlobalHooks(this.Handle);
            _drives = ProcessUtils.GetAllDriveLetters();
            _previousRedraw = false;
            _mostPopularLocations = new Dictionary<string, int>();
            
            _knownLocations = new List<string>
            {
                "Computer",
                "Recent Places",
                "Desktop",
                "Libraries",
                "Network",
                "Control Panel",
                "Recycle Bin"
            };
            
            _globalHooks.Shell.WindowActivated += new Monitor.GlobalHooks.WindowEventHandler(_OnShellActivated);
            _globalHooks.Shell.Redraw += new Monitor.GlobalHooks.WindowEventHandler(_OnShellRedraw);
        }
        #endregion

        #region Override
        protected override void WndProc(ref Message m)
        {
            // Check to see if we've received any Windows messages telling us about our hooks
            if (_globalHooks != null)
                _globalHooks.ProcessWindowMessage(ref m);

            base.WndProc(ref m);
        }
        #endregion

        #region Event Handlers
        private void _OnShellActivated(IntPtr handle)
        {
            AddToList(handle, "Activate");
        }

        private void _OnShellRedraw(IntPtr handle)
        {
            AddToList(handle, "Redraw");
        }
        #endregion

        private void AddToList(IntPtr handle, string action)
        {
            bool isExplorer = ProcessUtils.isExplorer(handle);
            bool isPath;
            bool isSearch;
            bool isKnownLocation;
            bool sameEntry;
            string windowName;

            if (isExplorer)
            {
                windowName = ProcessUtils.GetWindowName(handle);
                isPath = ProcessUtils.isPath(ProcessUtils.GetWindowName(handle), _drives);
                isKnownLocation = ProcessUtils.isKnownLocation(ProcessUtils.GetWindowName(handle), _knownLocations);
                sameEntry = windowName.Equals(_previousEntry);
                isSearch = windowName.Contains("search-ms");

                if (sameEntry)
                    return;

                if (isPath || isSearch || isKnownLocation)
                {
                    if (isPath || isKnownLocation)
                    {
                        if (_mostPopularLocations.ContainsKey(windowName))
                            _mostPopularLocations[windowName]++;
                        else
                            _mostPopularLocations.Add(windowName, 1);
                    }

                    _previousRedraw = action.Equals("Redraw");
                    _previousEntry = windowName;
                    if (isSearch)
                    {
                        action += "(search)";
                        windowName = ParseSearch(windowName);
                    }

                    ListViewItem item = new ListViewItem(action);
                    item.SubItems.Add(windowName);
                    listView1.Items.Add(item);
                    
                    listView1.Items[listView1.Items.Count - 1].EnsureVisible();
                }
            }
        }

        private string ParseSearch(string windowName)
        {
            String ans = "",str;
            int indexStart, indexEnd;

            indexEnd = windowName.IndexOf("search-ms");
            ans += "Searched: " + windowName.Substring(0, indexEnd - 3);

            str = "Search%20Results%20in%20";
            indexStart = windowName.IndexOf(str);
            indexEnd = windowName.IndexOf("&crumb");

            ans += " [" + windowName.Substring(indexStart + str.Length, indexEnd - (indexStart + str.Length)) + "]";

            return ans;
        }

        #region Buttons
        private void button1_Click(object sender, EventArgs e)
        {
            _globalHooks.Shell.Start();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            _globalHooks.Shell.Stop();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            listView1.Items.Clear();
        }
        #endregion
    }
}
